home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / WFC010.ZIP / SRC / DRAWGRID.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-07  |  28.0 KB  |  1,096 lines

  1. #include <wfc.h>
  2. #pragma hdrstop
  3.  
  4. /*
  5. ** Author: Samuel R. Blackburn
  6. ** CI$: 76300,326
  7. ** Internet: sammy@sed.csc.com
  8. **
  9. ** You can use it any way you like as long as you don't try to sell it.
  10. **
  11. ** Any attempt to sell WFC in source code form must have the permission
  12. ** of the original author. You can produce commercial executables with
  13. ** WFC but you can't sell WFC.
  14. **
  15. ** Copyright, 1995, Samuel R. Blackburn
  16. **
  17. ** $Workfile: $
  18. ** $Revision: $
  19. ** $Modtime: $
  20. */
  21.  
  22. #if defined( _DEBUG )
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #endif
  26.  
  27. IMPLEMENT_SERIAL( CDrawingObjectGrid, CObject, 1 )
  28. IMPLEMENT_SERIAL( CLabeledGrid, CDrawingObjectGrid, 1 )
  29.  
  30. #if defined( _DEBUG )
  31. #define new DEBUG_NEW
  32. #endif
  33.  
  34. CDrawingObjectGrid::CDrawingObjectGrid()
  35. {
  36.    m_Initialize();
  37. }
  38.  
  39. CDrawingObjectGrid::CDrawingObjectGrid( DWORD number_of_rows, DWORD number_of_columns )
  40. {
  41.    m_Initialize();
  42.    SetSize( number_of_rows, number_of_columns );
  43. }
  44.  
  45. CDrawingObjectGrid::~CDrawingObjectGrid()
  46. {
  47.    RemoveAll();
  48. }
  49.  
  50. void CDrawingObjectGrid::Draw( CDC& device_context )
  51. {
  52.    int index              = 0;
  53.    int number_of_elements = m_ObjectArray.GetSize();
  54.  
  55.    CRectangle *object_p = (CRectangle *) NULL;
  56.  
  57.    while( index < number_of_elements )
  58.    {
  59.       object_p = (CRectangle *) m_ObjectArray[ index ];
  60.       
  61.       if ( object_p != NULL )
  62.       {
  63.          object_p->Draw( device_context );
  64.       }
  65.  
  66.       index++;
  67.    }
  68. }
  69.  
  70. #if defined( _DEBUG )
  71.  
  72. void CDrawingObjectGrid::Dump( CDumpContext& dump_context ) const
  73. {
  74.    CObject::Dump( dump_context );
  75.  
  76.    dump_context << "{\n";
  77.    dump_context << "   m_Name = \""            << m_Name              << "\"\n";
  78.    dump_context << "   m_NumberOfRows = "      << m_NumberOfRows      << "\n";
  79.    dump_context << "   m_NumberOfColumns = "   << m_NumberOfColumns   << "\n";
  80.    dump_context << "   m_VerticalSpacing = "   << m_VerticalSpacing   << "\n";
  81.    dump_context << "   m_HorizontalSpacing = " << m_HorizontalSpacing << "\n";
  82.  
  83.    m_ObjectArray.Dump( dump_context );
  84.    dump_context << "}\n";
  85. }
  86.  
  87. #endif // _DEBUG
  88.  
  89. CRectangle*& CDrawingObjectGrid::ElementAt( DWORD row_number, DWORD column_number )
  90. {
  91.    return( (CRectangle *&) m_ObjectArray.ElementAt( ( row_number * m_NumberOfColumns ) + column_number ) );
  92. }
  93.  
  94. CRectangle* CDrawingObjectGrid::GetAt( DWORD row_number, DWORD column_number )
  95. {
  96.    return( (CRectangle *) m_ObjectArray.ElementAt( ( row_number * m_NumberOfColumns ) + column_number ) );
  97. }
  98.  
  99. DWORD CDrawingObjectGrid::GetHeight( void ) const
  100. {
  101.    DWORD height = 0;
  102.    DWORD index  = 0;
  103.  
  104.    CRectangle *object_p = (CRectangle *) NULL;
  105.  
  106.    while( index < m_NumberOfRows )
  107.    {
  108.       object_p = (CRectangle *) m_ObjectArray[ index ];
  109.  
  110.       if ( object_p != NULL )
  111.       {
  112.          height += object_p->GetHeight();
  113.          height += m_VerticalSpacing;
  114.       }
  115.  
  116.       index++;
  117.    }
  118.  
  119.    if ( m_NumberOfRows > 0 )
  120.    {
  121.       height -= m_VerticalSpacing;
  122.    }
  123.  
  124.    return( height );
  125. }
  126.  
  127. int CDrawingObjectGrid::GetHorizontalSpacing( void ) const
  128. {
  129.    return( m_HorizontalSpacing );
  130. }
  131.  
  132. BOOL CDrawingObjectGrid::GetIndexFromPoint( DWORD& _row_index, DWORD& _column_index, const CPoint& point )
  133. {
  134.    DWORD row_index    = 0;
  135.    DWORD column_index = 0;
  136.  
  137.    CRectangle *object_p = (CRectangle *) NULL;
  138.  
  139.    CRect rectangle;
  140.  
  141.    while( row_index < (DWORD) m_NumberOfRows )
  142.    {
  143.       column_index = 0;
  144.  
  145.       while( column_index < (DWORD) m_NumberOfColumns )
  146.       {
  147.          object_p = GetAt( row_index, column_index );
  148.  
  149.          if ( object_p != NULL )
  150.          {
  151.             object_p->GetRectangle( rectangle );
  152.  
  153.             if ( rectangle.PtInRect( point ) == TRUE )
  154.             {
  155.                _row_index    = row_index;
  156.                _column_index = column_index;
  157.                return( TRUE );
  158.             }
  159.          }
  160.  
  161.          column_index++;
  162.       }
  163.  
  164.       row_index++;
  165.    }
  166.  
  167.    return( FALSE );
  168. }
  169.  
  170. void CDrawingObjectGrid::GetName( CString& name_of_grid ) const
  171. {
  172.    name_of_grid = m_Name;
  173. }
  174.  
  175. DWORD CDrawingObjectGrid::GetNumberOfColumns( void ) const
  176. {
  177.    return( m_NumberOfColumns );
  178. }
  179.  
  180. DWORD CDrawingObjectGrid::GetNumberOfRows( void ) const
  181. {
  182.    return( m_NumberOfRows );
  183. }
  184.  
  185. void CDrawingObjectGrid::GetRectangle( CRect& rectangle ) const
  186. {
  187.    if ( m_ObjectArray[ 0 ] == NULL )
  188.    {
  189.       rectangle.SetRectEmpty();
  190.       return;
  191.    }
  192.  
  193.    CRectangle *object_p = (CRectangle *) m_ObjectArray[ 0 ];
  194.  
  195.    if ( object_p == NULL )
  196.    {
  197.       rectangle.SetRectEmpty();
  198.       return;
  199.    }
  200.  
  201.    CRect object_rectangle;
  202.  
  203.    object_p->GetRectangle( object_rectangle );
  204.  
  205.    rectangle.left   = object_rectangle.left;
  206.    rectangle.top    = object_rectangle.top;
  207.    rectangle.right  = rectangle.left + GetWidth();
  208.    rectangle.bottom = rectangle.top  + GetHeight();
  209. }
  210.  
  211. DWORD CDrawingObjectGrid::GetVerticalSpacing( void ) const
  212. {
  213.    return( m_VerticalSpacing );
  214. }
  215.  
  216. DWORD CDrawingObjectGrid::GetWidth( void ) const
  217. {
  218.    DWORD width = 0;
  219.    DWORD index = 0;
  220.  
  221.    CRectangle *object_p = NULL;
  222.  
  223.    while( index < m_NumberOfColumns )
  224.    {
  225.       object_p = (CRectangle *) m_ObjectArray[ index ];
  226.  
  227.       if ( object_p != NULL )
  228.       {
  229.          width += object_p->GetWidth();
  230.          width += m_HorizontalSpacing;
  231.       }
  232.  
  233.       index++;
  234.    }
  235.  
  236.    if ( m_NumberOfColumns > 0 )
  237.    {
  238.       width -= m_HorizontalSpacing;
  239.    }
  240.  
  241.    return( width );
  242. }
  243.  
  244. void CDrawingObjectGrid::m_Initialize( void )
  245. {
  246.    RemoveAll();
  247.    m_VerticalSpacing   = 1;
  248.    m_HorizontalSpacing = 1;
  249.    m_NumberOfRows      = 0;
  250.    m_NumberOfColumns   = 0;
  251.  
  252.    m_Name.Empty();
  253. }
  254.  
  255. void CDrawingObjectGrid::RemoveAll( void )
  256. {
  257.    int index = 0;
  258.    int number_of_elements = m_ObjectArray.GetSize();
  259.  
  260.    CRectangle *object_p = NULL;
  261.  
  262.    while( index < number_of_elements )
  263.    {
  264.       object_p = (CRectangle *) m_ObjectArray[ index ];
  265.  
  266.       if ( object_p != NULL )
  267.       {
  268.          delete object_p;
  269.       }
  270.  
  271.       index++;
  272.    }
  273.  
  274.    m_ObjectArray.RemoveAll();
  275.  
  276.    m_NumberOfRows    = 0;
  277.    m_NumberOfColumns = 0;
  278. }
  279.  
  280. void CDrawingObjectGrid::Serialize( CArchive& archive )
  281. {
  282.    CObject::Serialize( archive );
  283.  
  284.    if ( archive.IsStoring() )
  285.    {
  286.       archive << m_NumberOfRows;
  287.       archive << m_NumberOfColumns;
  288.       archive << m_VerticalSpacing;
  289.       archive << m_HorizontalSpacing;
  290.       archive << m_Name;
  291.    }
  292.    else
  293.    {
  294.       archive >> m_NumberOfRows;
  295.       archive >> m_NumberOfColumns;
  296.       archive >> m_VerticalSpacing;
  297.       archive >> m_HorizontalSpacing;
  298.       archive >> m_Name;
  299.    }
  300.  
  301.    m_ObjectArray.Serialize( archive );
  302. }
  303.  
  304. void CDrawingObjectGrid::SetAt( DWORD row_number, DWORD column_number, CRectangle *new_element )
  305. {
  306.    DWORD index = ( row_number * m_NumberOfColumns ) + column_number;
  307.  
  308.    CRectangle *object_p = (CRectangle *) m_ObjectArray[ index ];
  309.  
  310.    if ( object_p != NULL )
  311.    {
  312.       if ( object_p == new_element )
  313.       {
  314.          return;
  315.       }
  316.       else
  317.       {
  318.          delete object_p;
  319.       }
  320.    }
  321.  
  322.    m_ObjectArray[ index ] = new_element;
  323. }
  324.  
  325. void CDrawingObjectGrid::SetFillColor( DWORD row_number, DWORD column_number, COLORREF color )
  326. {
  327.    CRectangle *object_p = GetAt( row_number, column_number );
  328.  
  329.    if ( object_p != NULL )
  330.    {
  331.       object_p->SetFillColor( color );
  332.    }
  333. }
  334.  
  335. void CDrawingObjectGrid::SetHorizontalSpacing( DWORD horizontal_spacing )
  336. {
  337.    m_HorizontalSpacing = horizontal_spacing;
  338. }
  339.  
  340. void CDrawingObjectGrid::SetLineColor( DWORD row_number, DWORD column_number, COLORREF color )
  341. {
  342.    CRectangle *object_p = GetAt( row_number, column_number );
  343.  
  344.    if ( object_p != NULL )
  345.    {
  346.       object_p->SetLineColor( color );
  347.    }
  348. }
  349.  
  350. void CDrawingObjectGrid::SetName( LPCTSTR name_of_grid )
  351. {
  352.    if ( name_of_grid != NULL )
  353.    {
  354.       m_Name = name_of_grid;
  355.    }
  356.    else
  357.    {
  358.       m_Name.Empty();
  359.    }
  360. }
  361.  
  362. void CDrawingObjectGrid::SetRectangle( const CRect& source )
  363. {
  364.    if ( m_ObjectArray[ 0 ] == NULL )
  365.    {
  366.       return;
  367.    }
  368.  
  369.    CRectangle *object_p = (CRectangle *) m_ObjectArray[ 0 ];
  370.  
  371.    if ( object_p == NULL )
  372.    {
  373.       return;
  374.    }
  375.  
  376.    DWORD vertical_size   = object_p->GetHeight();
  377.    DWORD horizontal_size = object_p->GetWidth();
  378.  
  379.    DWORD vertical_location   = source.top;
  380.    DWORD horizontal_location = source.left;
  381.  
  382.    DWORD column_index = 0;
  383.    DWORD row_index    = 0;
  384.  
  385.    CPoint point;
  386.  
  387.    while( row_index < m_NumberOfRows )
  388.    {
  389.       column_index        = 0;
  390.       horizontal_location = source.left;
  391.  
  392.       while( column_index < m_NumberOfColumns )
  393.       {
  394.          point.x = horizontal_location;
  395.          point.y = vertical_location;
  396.  
  397.          object_p = GetAt( row_index, column_index );
  398.  
  399.          if ( object_p != NULL )
  400.          {
  401.             object_p->SetLocation( point );
  402.          }
  403.  
  404.          horizontal_location += (horizontal_size + m_HorizontalSpacing );
  405.          column_index++;
  406.       }
  407.  
  408.       vertical_location += ( vertical_size + m_VerticalSpacing );
  409.       row_index++;
  410.    }
  411. }
  412.  
  413. void CDrawingObjectGrid::SetSize( DWORD number_of_rows, DWORD number_of_columns )
  414. {
  415.    RemoveAll();
  416.  
  417.    m_NumberOfRows    = number_of_rows;
  418.    m_NumberOfColumns = number_of_columns;
  419.    m_ObjectArray.SetSize( m_NumberOfRows * m_NumberOfColumns );
  420. }
  421.  
  422. void CDrawingObjectGrid::SetVerticalSpacing( DWORD vertical_spacing )
  423. {
  424.    m_VerticalSpacing = vertical_spacing;
  425. }
  426.  
  427. /*
  428. ** And now for some labels
  429. */
  430.  
  431. CLabeledGrid::CLabeledGrid()
  432. {
  433.    m_Initialize();
  434. }
  435.  
  436. CLabeledGrid::CLabeledGrid( DWORD number_of_rows, DWORD number_of_columns )
  437. {
  438.    m_Initialize();
  439.    SetSize( number_of_rows, number_of_columns );
  440. }
  441.  
  442. CLabeledGrid::~CLabeledGrid()
  443. {
  444.    m_RowNamesFont.DeleteObject();
  445.    m_RowsTitleFont.DeleteObject();
  446.    m_ColumnNamesFont.DeleteObject();
  447.    m_ColumnsTitleFont.DeleteObject();
  448. }
  449.  
  450. void CLabeledGrid::Draw( CDC& device_context )
  451. {
  452.    /*
  453.    ** Go draw the CRectangles...
  454.    */
  455.  
  456.    CDrawingObjectGrid::Draw( device_context );
  457.  
  458.    int x_coordinate         = 0;
  459.    int y_coordinate         = 0;
  460.    int object_height        = 0;
  461.    int object_width         = 0;
  462.    int label_height         = 0;
  463.    int label_width          = 0;
  464.    int column_labels_offset = 0;
  465.    int row_labels_offset    = 0;
  466.  
  467.    CRectangle *rectangle_p = NULL;
  468.  
  469.    CRect rect;
  470.  
  471.    CString name;
  472.  
  473.    CSize size;
  474.  
  475.    DWORD index = 0;
  476.  
  477.    CFont *old_font = (CFont *) NULL;
  478.  
  479.    CString grid_name;
  480.  
  481.    old_font = device_context.SelectObject( &m_RowNamesFont );
  482.  
  483.    rectangle_p = GetAt( 0, 0 );
  484.    rectangle_p->GetRectangle( rect );
  485.  
  486.    if ( m_LabelOptions & LABELED_GRID_ROW_NAMES )
  487.    {
  488.       index = 0;
  489.  
  490.       device_context.SelectObject( &m_RowNamesFont );
  491.  
  492.       while( index < m_NumberOfRows )
  493.       {
  494.          rectangle_p = GetAt( index, 0 );
  495.  
  496.          rectangle_p->GetRectangle( rect );
  497.  
  498.          /*
  499.          ** Get the rectangle for the actual drawing objects...
  500.          **
  501.          **                rect.left (x_coordinate)
  502.          **                |
  503.          **                v
  504.          **     rect.top ->+-----+   +-----+   +-----+
  505.          ** (y_coordinate) |     |   |     |   |     |
  506.          **                | 0,0 |   | 0,1 |   | 0,2 |
  507.          **                |     |   |     |   |     |
  508.          **                +-----+   +-----+   +-----+
  509.          **
  510.          **                +-----+   +-----+   +-----+
  511.          **                |     |   |     |   |     |
  512.          **                | 1,0 |   | 1,1 |   | 1,2 |
  513.          **                |     |   |     |   |     |
  514.          **                +-----+   +-----+   +-----+
  515.          **
  516.          **                +-----+   +-----+   +-----+
  517.          **                |     |   |     |   |     |
  518.          **                | 2,0 |   | 2,1 |   | 2,2 |
  519.          **                |     |   |     |   |     |
  520.          **                +-----+   +-----+   +-----+
  521.          */
  522.  
  523.          x_coordinate = rect.left;
  524.          y_coordinate = rect.top;
  525.  
  526.          /*
  527.          ** Move the x_coordinate to the left to make room for the longest row title (the longest row title was determined
  528.          ** in the call to PrepareForPainting().
  529.          **
  530.          ** Horizontal Spacing is the distance betweeen drawing objects in the grid:
  531.          **
  532.          **                        m_HorizontalSpacing
  533.          **                        |
  534.          **                        v
  535.          **                       |-|
  536.          **                +-----+   +-----+   +-----+
  537.          **                |     |   |     |   |     |
  538.          **                | 0,0 |   | 0,1 |   | 0,2 |
  539.          **                |     |   |     |   |     |
  540.          **                +-----+   +-----+   +-----+
  541.          **
  542.          **                +-----+   +-----+   +-----+
  543.          **                |     |   |     |   |     |
  544.          **                | 1,0 |   | 1,1 |   | 1,2 |
  545.          **                |     |   |     |   |     |
  546.          **                +-----+   +-----+   +-----+
  547.          **
  548.          **                +-----+   +-----+   +-----+
  549.          **                |     |   |     |   |     |
  550.          **                | 2,0 |   | 2,1 |   | 2,2 |
  551.          **                |     |   |     |   |     |
  552.          **                +-----+   +-----+   +-----+
  553.          */
  554.  
  555.          x_coordinate -= ( m_NumberOfLogicalUnitsInLongestRowName + ( m_HorizontalSpacing * 2 ) + 1 );
  556.  
  557.          /*
  558.          ** Try to vertically center the row label in the space provided by the height of the object
  559.          */
  560.  
  561.          GetRowName( index, name );
  562.  
  563.          size = device_context.GetTextExtent( name, name.GetLength() );
  564.  
  565.          label_height  = size.cy;
  566.          object_height = rect.Height();
  567.  
  568.          y_coordinate += ( object_height / 2 );
  569.          y_coordinate -= ( label_height  / 2 );
  570.  
  571.          /*
  572.          ** Make sure we didn't go above the object
  573.          */
  574.  
  575.          if ( y_coordinate < rect.top )
  576.          {
  577.             y_coordinate = rect.top;
  578.          }
  579.  
  580.          /*
  581.          ** Now store where we are in case we have to paint the rows title
  582.          */
  583.  
  584.          row_labels_offset = x_coordinate - ( m_HorizontalSpacing + 1 );
  585.  
  586.          device_context.TextOut( x_coordinate, y_coordinate, name );
  587.  
  588.          index++;
  589.       }
  590.    }
  591.  
  592.    if ( m_LabelOptions & LABELED_GRID_COLUMN_NAMES )
  593.    {
  594.       index = 0;
  595.  
  596.       device_context.SelectObject( &m_ColumnNamesFont );
  597.  
  598.       while( index < m_NumberOfColumns )
  599.       {
  600.          rectangle_p = GetAt( 0, index );
  601.  
  602.          rectangle_p->GetRectangle( rect );
  603.  
  604.          GetColumnName( index, name );
  605.  
  606.          /*
  607.          ** Try to center the label
  608.          */
  609.  
  610.          x_coordinate = rect.left;
  611.  
  612.          size = device_context.GetTextExtent( name, name.GetLength() );
  613.  
  614.          column_labels_offset = m_VerticalSpacing + size.cy + 1;
  615.          y_coordinate = rect.top - column_labels_offset;
  616.  
  617.          if ( y_coordinate < 0 )
  618.          {
  619.             y_coordinate = 0;
  620.          }
  621.          
  622.          label_width  = size.cx;
  623.          object_width = rect.Width();
  624.  
  625.          x_coordinate += ( object_width / 2 );
  626.          x_coordinate -= ( label_width  / 2 );
  627.  
  628.          if ( x_coordinate < rect.left )
  629.          {
  630.             x_coordinate = rect.left;
  631.          }
  632.  
  633.          device_context.TextOut( x_coordinate, y_coordinate, name );
  634.  
  635.          index++;
  636.       }
  637.    }
  638.  
  639.    if ( m_LabelOptions & LABELED_GRID_COLUMNS_TITLE )
  640.    {
  641.       /*
  642.       ** Get the rectangle for the entire grid
  643.       */
  644.  
  645.       GetRectangle( rect );
  646.  
  647.       x_coordinate  = rect.left;
  648.       x_coordinate += rect.Width() / 2;
  649.       x_coordinate -= m_NumberOfLogicalUnitsInColumnsTitle / 2;
  650.  
  651.       GetColumnsTitle( name );
  652.       device_context.SelectObject( &m_ColumnsTitleFont );
  653.  
  654.       size = device_context.GetTextExtent( name, name.GetLength() );
  655.       
  656.       y_coordinate = rect.top - ( size.cy + column_labels_offset + m_VerticalSpacing + 1 );
  657.  
  658.       if ( y_coordinate < 0 )
  659.       {
  660.          y_coordinate = 0;
  661.       }
  662.  
  663.       device_context.TextOut( x_coordinate, y_coordinate, name );
  664.    }
  665.  
  666.    if ( m_LabelOptions & LABELED_GRID_ROWS_TITLE )
  667.    {
  668.       /*
  669.       ** Get the rectangle for the entire grid
  670.       */
  671.  
  672.       GetRectangle( rect );
  673.  
  674.       /*
  675.       ** Get the rectangle for the actual drawing objects...
  676.       **
  677.       **                rect.left (x_coordinate)
  678.       **                |
  679.       **                v
  680.       **                +-----+   +-----+   +-----+
  681.       **                |     |   |     |   |     |
  682.       **                | 0,0 |   | 0,1 |   | 0,2 |
  683.       **                |     |   |     |   |     |
  684.       **                +-----+   +-----+   +-----+
  685.       **
  686.       **                +-----+   +-----+   +-----+
  687.       **                |     |   |     |   |     |
  688.       **                | 1,0 |   | 1,1 |   | 1,2 |
  689.       **                |     |   |     |   |     |
  690.       **                +-----+   +-----+   +-----+
  691.       **
  692.       **                +-----+   +-----+   +-----+
  693.       **                |     |   |     |   |     |
  694.       **                | 2,0 |   | 2,1 |   | 2,2 |
  695.       **                |     |   |     |   |     |
  696.       **  rect.bottom ->+-----+   +-----+   +-----+
  697.       **  (y_coordinate)
  698.       */
  699.  
  700.       x_coordinate = rect.left;
  701.       y_coordinate = rect.bottom;
  702.  
  703.       GetRowsTitle( name );
  704.       device_context.SelectObject( &m_RowsTitleFont );
  705.  
  706.       size = device_context.GetTextExtent( name, name.GetLength() );
  707.  
  708.       /*
  709.       ** Now this is a little weird, remember that the rows title is turned so that it runs from the bottom
  710.       ** of the grid to the top. This means we need to move to the left of the grid by the number of logical
  711.       ** units in the *height* of the title. Usually we don't care about the height of a title when dealing
  712.       ** in the x-axis but since we turned the font so it will print vertically, the height of the title 
  713.       ** becomes the width (strange but true...).
  714.       */
  715.  
  716.       label_height = size.cy;
  717.  
  718.       //x_coordinate -= ( row_labels_offset + m_HorizontalSpacing + label_height + 1 );
  719.       x_coordinate -= ( row_labels_offset + label_height + m_HorizontalSpacing );
  720.  
  721.       y_coordinate -= rect.Height() / 2;
  722.       y_coordinate += m_NumberOfLogicalUnitsInRowsTitle / 2;
  723.  
  724.       device_context.TextOut( x_coordinate, y_coordinate, name );
  725.    }
  726.  
  727.    device_context.SelectObject( old_font );
  728. }
  729.  
  730. #if defined( _DEBUG )
  731.  
  732. void CLabeledGrid::Dump( CDumpContext& dump_context ) const
  733. {
  734.    CDrawingObjectGrid::Dump( dump_context );
  735.  
  736.    dump_context << "m_ColumnNames is";
  737.    m_ColumnNames.Dump( dump_context );
  738.    
  739.    dump_context << "m_RowNames is";
  740.    m_RowNames.Dump( dump_context );
  741.  
  742.    dump_context << "m_RowsTitle    = \"" << m_RowsTitle    << "\"\n";
  743.    dump_context << "m_ColumnsTitle = \"" << m_ColumnsTitle << "\"\n";
  744.  
  745.    dump_context << "m_ColumnFontSize = " << m_ColumnFontSize << "\n";
  746.    dump_context << "m_ColumnsTitleFontSize = " << m_ColumnsTitleFontSize << "\n";
  747.    dump_context << "m_RowFontSize = " << m_RowFontSize << "\n";
  748.    dump_context << "m_RowsTitleFontSize = " << m_RowsTitleFontSize << "\n";
  749.    dump_context << "m_NumberOfLogicalUnitsInLongestRowName = " << m_NumberOfLogicalUnitsInLongestRowName << "\n";
  750.    dump_context << "m_NumberOfLogicalUnitsInLongestColumnName = " << m_NumberOfLogicalUnitsInLongestColumnName << "\n";
  751.    dump_context << "m_NumberOfLogicalUnitsInRowsTitle = " << m_NumberOfLogicalUnitsInRowsTitle << "\n";
  752.    dump_context << "m_NumberOfLogicalUnitsInColumnsTitle = " << m_NumberOfLogicalUnitsInColumnsTitle << "\n";
  753.    dump_context << "m_LabelOptions = " << m_LabelOptions << "\n";
  754.  
  755.    dump_context << "m_RowNamesFont is ";
  756.    m_RowNamesFont.Dump( dump_context );
  757.  
  758.    dump_context << "m_ColumnNamesFont is ";
  759.    m_ColumnNamesFont.Dump( dump_context );
  760.    
  761.    dump_context << "m_RowsTitleFont is";
  762.    m_RowsTitleFont.Dump( dump_context );
  763.  
  764.    dump_context << "m_ColumnsTitleFont is";
  765.    m_ColumnsTitleFont.Dump( dump_context );
  766. }
  767.  
  768. #endif // _DEBUG
  769.  
  770. void CLabeledGrid::GetColumnName( DWORD column_number, CString& column_name ) const
  771. {
  772.    if ( column_number >= (DWORD) m_ColumnNames.GetSize() )
  773.    {
  774.       column_name.Empty();
  775.       return;
  776.    }
  777.  
  778.    column_name = m_ColumnNames[ column_number ];
  779. }
  780.  
  781. void CLabeledGrid::GetColumnsTitle( CString& columns_title ) const
  782. {
  783.    columns_title = m_ColumnsTitle;
  784. }
  785.  
  786. void CLabeledGrid::GetRowName( DWORD row_number, CString& row_name ) const
  787. {
  788.    if ( row_number >= (DWORD) m_RowNames.GetSize() )
  789.    {
  790.       row_name.Empty();
  791.       return;
  792.    }
  793.  
  794.    row_name = m_RowNames[ row_number ];
  795. }
  796.  
  797. void CLabeledGrid::GetRowsTitle( CString& rows_title ) const
  798. {
  799.    rows_title = m_RowsTitle;
  800. }
  801.  
  802. void CLabeledGrid::m_Initialize( void )
  803. {
  804.    m_ColumnFontSize                          = 0;
  805.    m_ColumnsTitleFontSize                    = 0;
  806.    m_RowFontSize                             = 0;
  807.    m_RowsTitleFontSize                       = 0;
  808.    m_NumberOfLogicalUnitsInLongestRowName    = 0;
  809.    m_NumberOfLogicalUnitsInLongestColumnName = 0;
  810.    m_NumberOfLogicalUnitsInRowsTitle         = 0;
  811.    m_NumberOfLogicalUnitsInColumnsTitle      = 0;
  812.    m_LabelOptions                            = 0;
  813.    m_RowsTitle.Empty();
  814.    m_ColumnsTitle.Empty();
  815. }
  816.  
  817. void CLabeledGrid::m_SetColumnFontSize( CDC& device_context, DWORD font_size )
  818. {
  819.    m_ColumnFontSize = font_size;
  820.  
  821.    TRY
  822.    {
  823.       LOGFONT lf;
  824.  
  825.       ::ZeroMemory( &lf, sizeof( lf ) );
  826.  
  827.       lf.lfHeight         = -::MulDiv( m_ColumnFontSize, device_context.GetDeviceCaps( LOGPIXELSY ), 72 );
  828.       lf.lfCharSet        = DEFAULT_CHARSET;
  829.       lf.lfQuality        = DEFAULT_QUALITY;
  830.       lf.lfWeight         = FW_NORMAL;
  831.       lf.lfClipPrecision  = CLIP_LH_ANGLES | CLIP_STROKE_PRECIS;
  832.       lf.lfPitchAndFamily = FF_SWISS;
  833.       lf.lfEscapement     = 0;
  834.  
  835.       m_ColumnNamesFont.CreateFontIndirect( &lf );
  836.    }
  837.    CATCH( CResourceException, e )
  838.    {
  839.       TRACE( "CLabeledGrid::m_SetColumnFontSize(), font creation failed\n" );
  840.       return;
  841.    }
  842.    END_CATCH
  843. }
  844.  
  845. void CLabeledGrid::m_SetColumnsTitleFontSize( CDC& device_context, DWORD font_size )
  846. {
  847.    m_ColumnsTitleFontSize = font_size;
  848.  
  849.    TRY
  850.    {
  851.       LOGFONT lf;
  852.  
  853.       ::ZeroMemory( &lf, sizeof( lf ) );
  854.  
  855.       lf.lfHeight         = -::MulDiv( m_ColumnsTitleFontSize, device_context.GetDeviceCaps( LOGPIXELSY ), 72 );
  856.       lf.lfCharSet        = DEFAULT_CHARSET;
  857.       lf.lfQuality        = DEFAULT_QUALITY;
  858.       lf.lfWeight         = FW_NORMAL;
  859.       lf.lfClipPrecision  = CLIP_LH_ANGLES | CLIP_STROKE_PRECIS;
  860.       lf.lfPitchAndFamily = FF_SWISS;
  861.       lf.lfEscapement     = 0;
  862.  
  863.       m_ColumnsTitleFont.CreateFontIndirect( &lf );
  864.    }
  865.    CATCH( CResourceException, e )
  866.    {
  867.       TRACE( "CLabeledGrid::m_SetColumnsTitleFontSize(), font creation failed\n" );
  868.       return;
  869.    }
  870.    END_CATCH
  871. }
  872.  
  873. void CLabeledGrid::m_SetRowFontSize( CDC& device_context, DWORD font_size )
  874. {
  875.    m_RowFontSize = font_size;
  876.  
  877.    TRY
  878.    {
  879.       LOGFONT lf;
  880.  
  881.       ::ZeroMemory( &lf, sizeof( lf ) );
  882.  
  883.       lf.lfHeight         = -::MulDiv( m_RowFontSize, device_context.GetDeviceCaps( LOGPIXELSY ), 72 );
  884.       lf.lfCharSet        = DEFAULT_CHARSET;
  885.       lf.lfQuality        = DEFAULT_QUALITY;
  886.       lf.lfWeight         = FW_NORMAL;
  887.       lf.lfClipPrecision  = CLIP_LH_ANGLES | CLIP_STROKE_PRECIS;
  888.       lf.lfPitchAndFamily = FF_SWISS;
  889.       lf.lfEscapement     = 0;
  890.  
  891.       m_RowNamesFont.CreateFontIndirect( &lf );
  892.    }
  893.    CATCH( CResourceException, e )
  894.    {
  895.       TRACE( "CLabeledGrid::m_SetColumnFontSize(), font creation failed\n" );
  896.       return;
  897.    }
  898.    END_CATCH
  899. }
  900.  
  901. void CLabeledGrid::m_SetRowsTitleFontSize( CDC& device_context, DWORD font_size )
  902. {
  903.    m_RowsTitleFontSize = font_size;
  904.  
  905.    TRY
  906.    {
  907.       LOGFONT lf;
  908.  
  909.       ::ZeroMemory( &lf, sizeof( lf ) );
  910.  
  911.       lf.lfHeight         = -::MulDiv( m_RowsTitleFontSize, device_context.GetDeviceCaps( LOGPIXELSY ), 72 );
  912.       lf.lfCharSet        = DEFAULT_CHARSET;
  913.       lf.lfQuality        = DEFAULT_QUALITY;
  914.       lf.lfWeight         = FW_NORMAL;
  915.       lf.lfClipPrecision  = CLIP_LH_ANGLES | CLIP_STROKE_PRECIS;
  916.       lf.lfPitchAndFamily = FF_SWISS;
  917.       lf.lfEscapement     = 900;
  918.  
  919.       m_RowsTitleFont.CreateFontIndirect( &lf );
  920.    }
  921.    CATCH( CResourceException, e )
  922.    {
  923.       TRACE( "CLabeledGrid::m_SetColumnFontSize(), font creation failed\n" );
  924.       return;
  925.    }
  926.    END_CATCH
  927. }
  928.  
  929. void CLabeledGrid::PrepareForPainting( CDC&  device_context, 
  930.                                        DWORD row_font_size,
  931.                                        DWORD column_font_size,
  932.                                        DWORD rows_title_font_size,
  933.                                        DWORD columns_title_font_size )
  934. {
  935.    m_SetColumnFontSize( device_context, column_font_size );
  936.    m_SetRowFontSize( device_context, row_font_size );
  937.    m_SetColumnsTitleFontSize( device_context, columns_title_font_size );
  938.    m_SetRowsTitleFontSize( device_context, rows_title_font_size );
  939.  
  940.    CSize size;
  941.  
  942.    DWORD index         = 0;
  943.    DWORD biggest_value = 0;
  944.  
  945.    CFont *old_font = (CFont *) NULL;
  946.  
  947.    old_font = device_context.SelectObject( &m_RowsTitleFont );
  948.  
  949.    size = device_context.GetTextExtent( m_RowsTitle, m_RowsTitle.GetLength() );
  950.  
  951.    m_NumberOfLogicalUnitsInRowsTitle = size.cx;
  952.  
  953.    device_context.SelectObject( &m_ColumnsTitleFont );
  954.  
  955.    size = device_context.GetTextExtent( m_ColumnsTitle, m_ColumnsTitle.GetLength() );
  956.  
  957.    m_NumberOfLogicalUnitsInColumnsTitle = size.cx;
  958.  
  959.    device_context.SelectObject( &m_RowNamesFont );
  960.  
  961.    CString name;
  962.  
  963.    while( index < m_NumberOfRows )
  964.    {
  965.       GetRowName( index, name );
  966.  
  967.       if ( (DWORD) name.GetLength() > biggest_value )
  968.       {
  969.          size = device_context.GetTextExtent( name, name.GetLength() );
  970.       }
  971.  
  972.       index++;
  973.    }
  974.  
  975.    m_NumberOfLogicalUnitsInLongestRowName = size.cx;
  976.  
  977.    index         = 0;
  978.    biggest_value = 0;
  979.  
  980.    device_context.SelectObject( &m_ColumnNamesFont );
  981.  
  982.    while( index < m_NumberOfColumns )
  983.    {
  984.       GetColumnName( index, name );
  985.  
  986.       if ( (DWORD) name.GetLength() > biggest_value )
  987.       {
  988.          size = device_context.GetTextExtent( name, name.GetLength() );
  989.       }
  990.  
  991.       index++;
  992.    }
  993.  
  994.    m_NumberOfLogicalUnitsInLongestColumnName = size.cx;
  995.  
  996.    device_context.SelectObject( old_font );
  997. }
  998.  
  999. void CLabeledGrid::RemoveAll()
  1000. {
  1001.    CDrawingObjectGrid::RemoveAll();
  1002.  
  1003.    m_ColumnNames.RemoveAll();
  1004.    m_RowNames.RemoveAll();
  1005. }
  1006.  
  1007. void CLabeledGrid::Serialize( CArchive& archive )
  1008. {
  1009.    CDrawingObjectGrid::Serialize( archive );
  1010.  
  1011.    if ( archive.IsStoring() )
  1012.    {
  1013.       archive << m_ColumnsTitle;
  1014.       archive << m_RowsTitle;
  1015.    }
  1016.    else
  1017.    {
  1018.       archive >> m_ColumnsTitle;
  1019.       archive >> m_RowsTitle;
  1020.    }
  1021.  
  1022.    m_ColumnNames.Serialize( archive );
  1023.    m_RowNames.Serialize( archive );
  1024. }
  1025.  
  1026. void CLabeledGrid::SetColumnName( DWORD column_number, LPCTSTR column_name )
  1027. {
  1028.    if ( column_number > m_NumberOfColumns )
  1029.    {
  1030.       return;
  1031.    }
  1032.  
  1033.    if ( column_name == NULL )
  1034.    {
  1035.       m_ColumnNames.SetAt( column_number, "" );
  1036.    }
  1037.    else
  1038.    {
  1039.       m_ColumnNames.SetAt( column_number, column_name );
  1040.    }
  1041. }
  1042.  
  1043. void CLabeledGrid::SetColumnsTitle( LPCTSTR columns_title )
  1044. {
  1045.    if ( columns_title == NULL )
  1046.    {
  1047.       m_ColumnsTitle.Empty();
  1048.    }
  1049.    else
  1050.    {
  1051.       m_ColumnsTitle = columns_title;
  1052.    }
  1053. }
  1054.  
  1055. void CLabeledGrid::SetLabelOptions( DWORD options )
  1056. {
  1057.    m_LabelOptions = options;
  1058. }
  1059.  
  1060. void CLabeledGrid::SetRowName( DWORD row_number, LPCTSTR row_name )
  1061. {
  1062.    if ( row_number > m_NumberOfRows )
  1063.    {
  1064.       return;
  1065.    }
  1066.  
  1067.    if ( row_name == NULL )
  1068.    {
  1069.       m_RowNames.SetAt( row_number, "" );
  1070.    }
  1071.    else
  1072.    {
  1073.       m_RowNames.SetAt( row_number, row_name );
  1074.    }
  1075. }
  1076.  
  1077. void CLabeledGrid::SetRowsTitle( LPCTSTR rows_title )
  1078. {
  1079.    if ( rows_title == NULL )
  1080.    {
  1081.       m_RowsTitle.Empty();
  1082.    }
  1083.    else
  1084.    {
  1085.       m_RowsTitle = rows_title;
  1086.    }
  1087. }
  1088.  
  1089. void CLabeledGrid::SetSize( DWORD number_of_rows, DWORD number_of_columns )
  1090. {
  1091.    CDrawingObjectGrid::SetSize( number_of_rows, number_of_columns );
  1092.  
  1093.    m_ColumnNames.SetSize( m_NumberOfColumns );
  1094.    m_RowNames.SetSize( m_NumberOfRows );
  1095. }
  1096.